/* 
 * Author: aple
 *
 * Created on 2015年10月9日, 上午10:07
 */

#ifndef SIMP_LOG_M_H
#define	SIMP_LOG_M_H

#include "stdint.h"
#include "rtctime.h"

#ifdef	__cplusplus
extern "C" {
#endif	

	typedef struct 
	{
		uint32_t blocks;
		uint32_t blocks_per_page;
		uint32_t site_start;
		uint32_t site_next;
	} simp_log_info_type;

	typedef struct
	{
		void (*save)(void);
		void (*save_verify)(void);
		void (*init)(void);
		void (*read)(uint32_t site, void *pdat);
		int32_t (*site_fore)(int32_t site, int32_t fore_amount);
		int32_t (*quick_search)(sig_time_type time, int8_t mode);
		int32_t (*head_search)(int32_t num, int32_t *site_des);
	}simp_log_api_type;

	typedef struct 
	{
		uint32_t addr_base;                          //必须对齐page_size边界
		uint32_t total_size;                         //必须为page_size的整数倍，且至少为4倍
		uint16_t page_size;                          //必须为2^n
		uint16_t dat_size;                           //必须为2^n，且最小为4
		void *pdat;                                  //必须为4字节对齐的地址
		simp_log_info_type * info;
		void (*Erase)(uint32_t AddrBase);                /*擦除*/
		void (*Program)(uint32_t Addr, uint32_t dat);    /*编程一字*/
		uint32_t (*Read)(uint32_t Addr);                 /*读取一字*/
		const simp_log_api_type * api;
	} simp_log_type;


void simp_log_save(const simp_log_type * cfg);
void simp_log_save_verify(const simp_log_type * cfg);
void simp_log_init(const simp_log_type * cfg);
void simp_log_read(const simp_log_type * cfg, uint32_t site, void *pdat);
int32_t simp_log_site_fore(const simp_log_type * cfg, int32_t site, int32_t fore_amount);
int32_t simp_log_head_search(const simp_log_type * cfg, int32_t num, int32_t *site_des);
	
/*-----------------------------------------------------------------------------------------------------*
 * 快速搜索，内部采用二分搜索法，从start到next-1区间
 * mode: 0(未命中目标时返回-1)，-1(未命中目标时返回小于目标值的位置)，1(未命中目标时返回大于目标值的位置)
 * return 返回-1代表未搜到指定结果， +数指向搜索结果位置
 *-----------------------------------------------------------------------------------------------------*/
int32_t simp_log_quick_search(const simp_log_type * cfg, sig_time_type time, int8_t mode);

/*-----------------------------------------------------------------------------------------------------*
* API
*-----------------------------------------------------------------------------------------------------*/
	#define simp_log_api_make(obj)											\
	void obj##_save(void){ simp_log_save(&obj);}							\
	void obj##_save_verify(void){ simp_log_save_verify(&obj);}				\
	void obj##_init(void ){ simp_log_init(&obj);}							\
	void obj##_read(uint32_t site, void *pdat)								\
		{ simp_log_read(&obj, site, pdat);}									\
	int32_t obj##_site_fore(int32_t site, int32_t fore_amount)				\
		{ return simp_log_site_fore(&obj, site, fore_amount);}				\
	int32_t obj##_quick_search(sig_time_type time, int8_t mode)				\
		{ return simp_log_quick_search(&obj, time, mode);}					\
	int32_t obj##_head_search(int32_t num, int32_t *site_des)				\
		{ return simp_log_head_search(&obj, num, site_des);}				\
	const simp_log_api_type  obj##_api = {									\
		obj##_save,															\
		obj##_save_verify,													\
		obj##_init,															\
		obj##_read,															\
		obj##_site_fore,													\
		obj##_quick_search													\
		obj##_head_search													\
	}
#define simp_log_api_ref(obj)	extern const simp_log_api_type obj##_api
#define simp_log_api_name(obj)	&obj##_api
	
#ifdef	__cplusplus
}
#endif

#endif	/* SIMP_LOG_M_H */
